package com.tbit.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
 * Base64 工具类
 *
 * @author <a href="mailto:zhang.zhiliang@tbit.com.cn">Zhang ZhiLiang</a>
 * @version 1.0
 * @see <a href="http://adsl1.tbit.com.cn:21490/pages/viewpage.action?pageId=82182491">订单号规范</a>
 * @since 2025/2/17
 */
public class Base64ImageUtil {
    /**
     * 将 Base64 字符串转换为 InputStream
     *
     * @param base64Str Base64 字符串（可能包含头部信息，如 "data:image/png;base64,"）
     * @return 返回生成的 InputStream 对象
     * @throws IOException 如果解码失败
     */
    public static ByteArrayInputStream base64ToInputStream(String base64Str) throws IOException {
        if (base64Str == null || base64Str.isEmpty()) {
            throw new IllegalArgumentException("Base64 字符串不能为空");
        }
        // 清理 Base64 字符串
        base64Str = base64Str.replaceAll("\\r|\\n", "");
        try {
            // 解码Base64字符串为字节数组
            byte[] decodedBytes = Base64.getDecoder().decode(base64Str);
            // 将字节数组转换为InputStream
            return new ByteArrayInputStream(decodedBytes);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("无效的Base64字符串", e);
        }
    }

    /**
     * 将 InputStream 转换为 Base64 字符串
     *
     * @param inputStream 输入流
     * @return Base64 字符串
     * @throws IOException 如果读取失败
     */
    public static String inputStreamToBase64(InputStream inputStream) throws IOException {
        if (inputStream == null) {
            throw new IllegalArgumentException("输入流不能为空");
        }
        // 将字节数组编码为 Base64 字符串
        return Base64.getEncoder().encodeToString(readAllBytes(inputStream));
    }

    /**
     * 将 InputStream 读取为字节数组
     *
     * @param inputStream 输入流
     * @return 字节数组
     * @throws IOException 如果读取输入流时发生错误
     */
    private static byte[] readAllBytes(InputStream inputStream) throws IOException {
        try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
            byte[] data = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, bytesRead);
            }
            buffer.flush();
            return buffer.toByteArray();
        }
    }

    /**
     * 校验字符串是否符合 Base64 编码规则，并输出非法字符
     *
     * @param input 待校验的字符串
     * @return 如果符合 Base64 编码规则，返回 true；否则返回 false
     */
    public static boolean isValidBase64(String input) {
        if (input == null || input.isEmpty()) {
            System.out.println("输入为空或 null，不符合 Base64 规则");
            return false; // 空字符串或 null 不符合 Base64 规则
        }
        input = input.replaceAll("\\r|\\n", "");
        // 定义合法的 Base64 字符集
        String base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        List<Character> illegalChars = new ArrayList<>();

        // 遍历字符串，找出非法字符
        for (char c : input.toCharArray()) {
            if (base64Chars.indexOf(c) == -1) {
                illegalChars.add(c);
            }
        }

        // 输出非法字符
        if (!illegalChars.isEmpty()) {
            System.out.println("发现非法字符: " + illegalChars);
            return false; // 包含非法字符，直接返回 false
        }

        // 检查长度是否符合 Base64 的规则（必须是 4 的倍数）
        int length = input.length();
        int mod = length % 4;
        if (mod != 0) {
            System.out.println("Base64 字符串长度不是 4 的倍数，可能缺少填充字符 '='");
            return false;
        }

        try {
            // 尝试解码，验证是否能成功
            java.util.Base64.getDecoder().decode(input);
            return true; // 解码成功，说明是合法的 Base64 字符串
        } catch (IllegalArgumentException e) {
            System.out.println("Base64 解码失败，可能包含非法字符或格式错误");
            return false;
        }
    }
}
